package com.gimi.cloud.bbp.manage.common.interceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gimi.cloud.bbp.common.annotation.RequestLog;
import com.gimi.cloud.bbp.common.enums.ResponseCodeEnum;
import com.gimi.cloud.bbp.common.exception.MsgException;
import com.gimi.cloud.bbp.common.utils.JsonUtil;
import com.gimi.cloud.bbp.dto.base.BaseDTO;
import com.gimi.cloud.bbp.dto.log.LogManageRequestDTO;
import com.gimi.cloud.bbp.manage.service.log.LogManageRequestService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Component
public class RequestLogInterceptor {
	private static final Logger logger = LoggerFactory.getLogger(RequestLogInterceptor.class);
	@Autowired
	private LogManageRequestService logManageRequestService;

	@Pointcut("@annotation(com.gimi.cloud.bbp.common.annotation.RequestLog)")
	public void requestLogPointCut() {
	}

	@Around("requestLogPointCut()")
	public Object Interceptor(ProceedingJoinPoint pjp) {
		MethodSignature signature = (MethodSignature) pjp.getSignature();
		// 获取被拦截的方法
		Method method = signature.getMethod();
		Object result = null;
		Object[] args = pjp.getArgs();
		LogManageRequestDTO logRequest = new LogManageRequestDTO();
		logRequest.setReTime(new Date());
		logRequest.setReMethod(method.getDeclaringClass().getName()+"."+signature.getName());
		JSONObject params = new JSONObject();
		int i= 1;
		BaseDTO baseDTO = null;
		HttpServletRequest request = null;
		for (Object arg : args) {
			if(arg instanceof HttpServletResponse || arg instanceof HttpServletRequest){
				if(arg instanceof HttpServletRequest){
					request = (HttpServletRequest)arg;
				}
				continue;
			}
			if (arg instanceof BaseDTO) {
				baseDTO = (BaseDTO) arg;
			}
			params.put("params_"+i, JsonUtil.toJson(arg));
			i++;
		}
		if(null != baseDTO){
			logRequest.setMaId(baseDTO.getUid());
			logRequest.setMaName(baseDTO.getUname());
			logRequest.setReIp(baseDTO.getIp());
			logRequest.setReServiceName(baseDTO.getServiceName());
		}
		if(null != request){
			logRequest.setReUrl(request.getRequestURI());
		}
		RequestLog requestLog = method.getAnnotation(RequestLog.class);
		boolean isLogResult = false;
		if(null != requestLog){
			logRequest.setReTitle(requestLog.title());
			logRequest.setReType(requestLog.type());
			//如果记录请求参数，则记录
			if(requestLog.isLogParam()){
				logRequest.setReParams(params.toJSONString());
			}
			isLogResult = requestLog.isLogResult();
		}
		try {
			logRequest = logManageRequestService.saveOrUpdate(logRequest);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		try {
			if (null == result) {
				result = pjp.proceed();
			}
		} catch (Throwable e) {
			logRequest.setReResptime(new Date());
			logRequest.setReResult("系统异常：" + e.getMessage());
			try {
                logManageRequestService.saveOrUpdate(logRequest);
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			logger.error("请求异常：", e);
			throw new MsgException(ResponseCodeEnum.EXCEED_THE_LOAD, e.getMessage());
		}
		logRequest.setReResptime(new Date());
		if(isLogResult){
			logRequest.setReResult(JSON.toJSONString(result));
		}
		try {
            logManageRequestService.saveOrUpdate(logRequest);
		} catch (Exception e) {
			e.printStackTrace();
		}
		logger.info("请求结束："+JSON.toJSONString(logRequest));
		return result;
	}
}
